using System;
using System.Threading;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine.Networking;
using System.IO.Compression;
//using System.Diagnostics;

namespace DanMuHelper.Logging
{
    /// <summary>
    /// 调试功能, 日志写入文件
    /// </summary>
    public class LogToFile : MonoBehaviour
    {
        private static readonly object _lock = new object();
        static readonly Queue<string> logs = new Queue<string>();
        private static LogToFile _instance;
        private static bool _isRunning = true;
        private static Thread _logThread;
        private static string LogDir;
        public static string LogFile { get; private set; }

#if UNITY_EDITOR || DEVELOPMENT_BUILD || GAME_RUNTIME_TEST
        private void Awake()
        {
            if (_instance)
            {
                Destroy(gameObject);
                return;
            }
            _instance = this;
            DontDestroyOnLoad(gameObject);

            LogDir = Path.Combine(Path.Combine(Application.dataPath, "../"), "DanmuHelperLogs");
            if (!Directory.Exists(LogDir))
            {
                Directory.CreateDirectory(LogDir);
            }

            // 检查并删除旧的日志文件，最多保留10份
            CleanOldLogs();

            var timeFormat = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
            LogFile = Path.Combine(LogDir, $"{timeFormat}.log");
            _logThread = new Thread(LogThread);
            _logThread.Start();
        }
#endif
        private void OnApplicationQuit()
        {
            if (this == _instance)
            {
                _isRunning = false;
                if (_logThread != null)
                {
                    try
                    {
                        _logThread.Join();
                    }
                    catch (Exception e)
                    {
                        Debug.LogException(e);
                    }
                }
            }
        }

#if UNITY_EDITOR || DEVELOPMENT_BUILD || GAME_RUNTIME_TEST
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void Startup()
        {
            var go = new GameObject("[DanmuHelperLogToFile]", typeof(LogToFile));
            // Debug.Log($"DanmuHelperLogToFile starting {go}...");
            Application.logMessageReceivedThreaded += OnReceiveLogMessage;
        }
#endif

        /// <summary>
        /// 多线程写文件
        /// </summary>
        static void LogThread()
        {
            //  Debug.Log($"Log will write to file: {LogFile}");
            var swap = new List<string>();
            using (StreamWriter fileStream = new StreamWriter(new FileStream(LogFile, FileMode.Create)))
            {
                while (_isRunning)
                {
                    lock (_lock)
                    {
                        if (logs.Count > 0)
                        {
                            swap.AddRange(logs);
                            logs.Clear();
                        }
                    }
                    if (swap.Count > 0)
                    {
                        for (int i = 0, c = swap.Count; i < c; i++)
                        {
                            fileStream.WriteLine(swap[i]);
                        }
                        swap.Clear();
                    }

                    //// TODO: 此处处理读文件请求
                    //if (false)
                    //{
                    //    fileStream.Flush();
                    //    var lines = File.ReadAllText(LogFile);
                    //}
                }
            }
            Debug.Log("Log to file quit.");
        }

        static void OnReceiveLogMessage(string logString, string stackTrace, LogType type)
        {
            if (type == LogType.Warning)
            {
                return;
            }
            var timeFmt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var msg = $"[{timeFmt}] [{type}] {logString}\n{stackTrace}";
            lock (_lock)
            {
                logs.Enqueue(msg);
            }
        }
        public static void CustonLog(string logString)
        {
            var timeFmt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var msg = $"[{timeFmt}] [{LogType.Log}] {logString}\n{""}";
            lock (_lock)
            {
                logs.Enqueue(msg);
            }
        }

        /// <summary>
        /// 清理旧的日志文件，最多保留10份
        /// </summary>
        private static void CleanOldLogs()
        {
            var logFiles = Directory.GetFiles(LogDir, "*.log")
                                    .Select(f => new FileInfo(f))
                                    .OrderBy(f => f.CreationTime)
                                    .ToList();

            while (logFiles.Count >= 10)
            {
                var oldestFile = logFiles.First();
                File.Delete(oldestFile.FullName);
                logFiles.Remove(oldestFile);
            }
        }
    }
}
